package org.micro.frame.mybatis.configuration;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * The Base DataSource Config
 *
 * @author lry
 */
@Slf4j
public class BaseDataSourceConfig {

    private String LOCATION_PATTERN = "classpath:mapper/%s/*Mapper.xml";
    private DataSource dataSource;
    private SqlSessionFactory sqlSessionFactory;

    /**
     * The Check @MultipleDataSource and Build Location Pattern
     */
    public BaseDataSourceConfig() {
        MultipleDataSource multipleDataSource = this.getClass().getAnnotation(MultipleDataSource.class);
        if (multipleDataSource == null) {
            throw new IllegalStateException("The not found @MultipleDataSource with " + this.getClass());
        }
        this.LOCATION_PATTERN = String.format(LOCATION_PATTERN, multipleDataSource.value());
    }

    /**
     * The Build DataSource
     *
     * @return
     */
    public DataSource buildDataSource() {
        return this.dataSource = DataSourceBuilder.create().build();
    }

    /**
     * The Build SqlSessionFactory
     *
     * @return
     */
    public SqlSessionFactory buildSqlSessionFactory(DataSource dataSource) {
        try {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(LOCATION_PATTERN));
            return this.sqlSessionFactory = bean.getObject();
        } catch (Exception e) {
            log.error("The build SqlSessionFactory is exception", e);
            return null;
        }
    }

    public MapperScannerConfigurer buildMapperScannerConfigurer(String basePackage, String sqlSessionTemplateBeanName) {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage(basePackage);
        mapperScannerConfigurer.setSqlSessionTemplateBeanName(sqlSessionTemplateBeanName);
        return mapperScannerConfigurer;
    }

    /**
     * The Build DataSourceTransactionManager
     *
     * @return
     */
    public DataSourceTransactionManager buildDataSourceTransactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    /**
     * The Build SqlSessionTemplate
     *
     * @return
     */
    public SqlSessionTemplate buildSqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}
